/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package control;

import model.Disciplina;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Date;
import java.util.regex.*;
import org.eclipse.persistence.logging.JavaLog;
import org.eclipse.persistence.logging.SessionLog;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.slf4j.*;

/**
 *
 * @author Rúiter
 */
public class Extraction {

    private final ArrayList<Disciplina> disciplinas;
    final static Logger logger = LoggerFactory.getLogger(Extraction.class);

    public Extraction() {
        this.disciplinas = new ArrayList<>();
    }

    public ArrayList extract(String url) {

        Document doc = null;

        try {

            try {
                //Documento que recebe o html da página a ser extraida
                doc = Jsoup.connect(url).get();
            } catch (IOException ex) {    //tratamento de exceção quando a URL não existe
                appendToFile(ex);
                logger.warn("{} inexistente.", url, ex);
                return disciplinas;
            } catch (Exception ex) {    //tratamento de exceção para o caso de exceção genérica
                appendToFile(ex);
                return disciplinas;
            }
            //Seleciona os elementos do HTML que contém a sigla e o Nome da Disciplina
            Elements titulo = doc.select("a[name]");
            //Seleciona os elementos do HTML que contém os pré-reqs, ementa, vetor de carga horária
            Elements paragrafo = doc.select("p");
            //Armazena em uma string os textos do paragrafo selecionado acima
            String substring = paragrafo.text();
            //Separa cada nova linha do paragrafo em um vetor de strings
            String[] prereq = substring.split("  ");

            //rotina que procura as siglas das pré-reqs
            for (int i = 0; i < prereq.length; i++) {
                //Procura elementos onde tem "Pré-Req.:" seguido de elementos do tipo XX-000
                String p = regexChecker("Pré-Req.:[//**[A-Z]{2}[0-9]{3}[ |/ ]{1}]+", prereq[i]);
                //Retira a parte da string que guarda a palavra "Pré-Req.:", deixando só as siglas
                prereq[i] = p.substring(10);
            }

            int j = 0;    //contador para a string de prereqs

            //rotina que retira a sigla e o nome da disciplina do titulo
            for (Element src : titulo) {
                int count = 0;
                //Separa a sigla do nome quando ocorre " - " na string
                String[] s = src.text().split(" - ");
                //adiciona a disciplina com sigla, nome e prereqs no vetor de disciplinas
                //AQUI SERÁ MUDADO PARA ADAPTAR AO BANCO DE DADOS
                Disciplina d = null;
                if ("N".equals(prereq[j])) {
                    d = new Disciplina(s[0], s[1]);
                } else {
                    d = new Disciplina(s[0], s[1], prereq[j]);
                }
                j++;
                disciplinas.add(d);
            }
            return disciplinas;
        } catch (NullPointerException ex) { //tratamento de exceção para página em branco.
            appendToFile(ex);
            return disciplinas;
        } catch (Exception ex) {    //tratamento de exceção para erro genérico 2.
            appendToFile(ex);
            return disciplinas;
        }
    }

    //funcão REGEX que encontra a expressão regular numa determinada string
    public static String regexChecker(String theRegex, String str2Check) {

        // You define your regular expression (REGEX) using Pattern
        Pattern checkRegex = Pattern.compile(theRegex);

        // Creates a Matcher object that searches the String for
        // anything that matches the REGEX
        Matcher regexMatcher = checkRegex.matcher(str2Check);

        // Cycle through the positive matches and print them to screen
        // Make sure string isn't empty and trim off any whitespace
        while (regexMatcher.find()) {
            if (regexMatcher.group().length() != 0) {
                return regexMatcher.group().trim();
            }
        }
        return null;
    }

    public static void appendToFile(Exception ex) {
        Date d = new Date();
        try {
            FileWriter fstream = new FileWriter("exception.txt", true);
            BufferedWriter out = new BufferedWriter(fstream);
            PrintWriter pWriter = new PrintWriter(out, true);
            pWriter.println(d + ": ");
            pWriter.println("Class: Extraction");
            ex.printStackTrace(pWriter);
            pWriter.println();
        } catch (Exception ie) {
            throw new RuntimeException("Could not write Exception to file", ie);
        }
    }
}
